// 注意:
// 有些结构体默认构造的内容不一定都是 0，erase_type 无参构造默认是初始化成 0
// 该结构的目的主要是擦除类型，有时内存分配了，但里面暂时未存放数据，可以使用此类型包装
// 等到它真正用到时，在以它实际的类型初始化。通过 need_initial 参数，控制是否使用构造函数初始化
#ifndef xpack_dumb_erase_type
#define xpack_dumb_erase_type
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::dumb_erase_type::inc
#include"define/base_type.hpp"
#include"macro/xalign.hpp"
#include"macro/xexport.hpp"
#include"macro/xmodify.hpp"
#include"macro/xnew.hpp"
#include"macro/xstruct.hpp"
#pragma pop_macro("xuser")

namespace mixc::dumb_erase_type{
    template<class type_t>
    xstruct(
        xtmpl(erase_type, type_t),
        xprif(m_value, u08[sizeof(type_t)]),
        xasso(type_t)
    )
    private:
        using etp = erase_type<type_t> *;
    public:
        erase_type(){} // 不初始化也不清空内容

        template<class ... args_t>
        requires(sizeof...(args_t) == 0)
        erase_type(need_initial_t need_initial, args_t && ... args){
            if (need_initial){
                xnew (m_value) type_t((args_t &&)args...); // 有些类型可能没有无参构造函数，所以需要用这种方式
            }
        }

        erase_type(type_t const & value, need_initial_t need_initial){
            if (need_initial){
                xnew (m_value) type_t(value);
            }
            else{
                this[0] = etp(xmodify(value))[0];
            }
        }

        erase_type(type_t && value, need_initial_t need_initial){
            if (need_initial){
                xnew (m_value) type_t((type_t &&)value);
            }
            else{
                this[0] = etp(xmodify(value))[0];
            }
        }

        void construct(type_t const & value){
            xnew (m_value) type_t(value);
        }

        void construct(type_t && value){
            xnew (m_value) type_t((type_t &&)value);
        }

        void assign_with_operator(type_t const & value){
            operator type_t &() = value;
        }

        void assign_with_operator(type_t && value){
            operator type_t &() = (type_t &&)value;
        }

        type_t * operator->(){
            return (type_t *)m_value;
        }

        const type_t * operator->() const {
            return (type_t *)m_value;
        }

        operator type_t & (){
            return *(type_t *)m_value;
        }

        operator type_t & () const {
            return *(type_t *)m_value;
        }

        constexpr uxx bytes() const {
            return sizeof(type_t);
        }
    $
}


namespace mixc::dumb_erase_type::origin{
    template<class type_t, uxx align_bytes_v = alignof(type_t)>
    struct xalign(align_bytes_v) erase_type : mixc::dumb_erase_type::erase_type<type_t>{
        using mixc::dumb_erase_type::erase_type<type_t>::erase_type;
    };

    template<>
    xstruct(
        xspec(erase_type, void, 0)
    ) $
}

#endif

xexport_space(mixc::dumb_erase_type::origin)